using System;
using System.Collections.Generic;

using Rsdn.Janus.ObjectModel;
using Rsdn.SmartApp;
using Rsdn.TreeGrid;

namespace Rsdn.Janus
{
    [Service(typeof(IActiveOutboxItemService))]
    internal class FeatureActiveOutboxItemService : IActiveOutboxItemService, IDisposable
    {

        public event EventHandler ActiveOutboxItemsChanged;
        private IServiceProvider _serviceProvider;

        public FeatureActiveOutboxItemService(IServiceProvider serviceProvider)
        {
            Features.Instance.OnAfterFeatureActivate += AfterFeatureActivate;
            SubscribeForSelectedNodeChanged();
            _serviceProvider = serviceProvider;
        }


        #region IDisposable Members

        public void Dispose()
        {
            Features.Instance.OnAfterFeatureActivate -= AfterFeatureActivate;
            IOutboxManagerBase outboxManager = GetCurrentOutboxManager(Features.Instance.ActiveFeature);
            UnsubscribeSelectedNodeChanged(outboxManager);
        }

        private void SubscribeForSelectedNodeChanged()
        {
            IOutboxManagerBase outboxManager = GetCurrentOutboxManager(Features.Instance.ActiveFeature);

            SubscribeForSelectedNodeChanged(outboxManager);
        }

        private void SubscribeForSelectedNodeChanged(IOutboxManagerBase outboxManager)
        {
            if (outboxManager != null)
            {
                // for the case if we have unattached event
                outboxManager.OutboxForm.SelectedNodesChanged -= OutboxForm_SelectedNodesChanged;
                outboxManager.OutboxForm.SelectedNodesChanged += OutboxForm_SelectedNodesChanged;
            }
        }

        private void UnsubscribeSelectedNodeChanged(IOutboxManagerBase outboxManager)
        {
            if (outboxManager != null)
            {
                outboxManager.OutboxForm.SelectedNodesChanged -= OutboxForm_SelectedNodesChanged;
            }
        }

        #endregion


        #region IOutboxDummyFormService Members

        /// <summary>
        /// Gets the current outbox manager.
        /// </summary>
        /// <returns></returns>
        public IOutboxManagerBase GetCurrentOutboxManager()
        {
            IFeature feature = Features.Instance.ActiveFeature;
            return GetCurrentOutboxManager(feature);
        }

        protected IOutboxManagerBase GetCurrentOutboxManager(IFeature feature)
        {
            IOutboxManagerBase ret = null;
            if (feature is OutboxFeature)
            {
                ret = ServiceProvider.GetRequiredService<IOutboxManager>();
            }
            else if (feature is DraftboxFeature)
            {
                ret = ServiceProvider.GetRequiredService<IDraftboxManager>();
            }
            return ret;
        }

        public List<ITreeNode> ActiveOutboxItems
        {
            get
            {
                IOutboxManagerBase currentOutboxManager = GetCurrentOutboxManager(Features.Instance.ActiveFeature);
                if (currentOutboxManager != null)
                {
                    return (List<ITreeNode>)currentOutboxManager.OutboxForm.SelectedNodes;
                }
                else
                {
                    return new List<ITreeNode>();
                }
            }
        }

        #endregion

        private void AfterFeatureActivate(IFeature oldFeature, IFeature newFeature)
        {
            if (oldFeature is OutboxFeature 
                || newFeature is OutboxFeature 
                || oldFeature is DraftboxFeature 
                || newFeature is DraftboxFeature)
            {
                IOutboxManagerBase oldOutboxManager = GetCurrentOutboxManager(oldFeature);

                UnsubscribeSelectedNodeChanged(oldOutboxManager);

                IOutboxManagerBase newOutboxManager = GetCurrentOutboxManager(newFeature);

                SubscribeForSelectedNodeChanged(newOutboxManager);

                OnActiveOutboxItemsChanged();
            }
        }

        void OutboxForm_SelectedNodesChanged(object sender, EventArgs e)
        {
            if (Features.Instance.ActiveFeature is OutboxFeature || Features.Instance.ActiveFeature is DraftboxFeature)
            {
                OnActiveOutboxItemsChanged();
            }
        }

        private void OnActiveOutboxItemsChanged()
        {
            if (ActiveOutboxItemsChanged != null)
            {
                ActiveOutboxItemsChanged(this, EventArgs.Empty);
            }
        }

        public IServiceProvider ServiceProvider
        {
            get { return _serviceProvider; }
        }

    }
}